package data.connector.rippling.client;

import com.fasterxml.jackson.databind.JsonNode;
import data.connector.rippling.api.base.BaseGenericService;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * ConnectWiseService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/6/5
 */
@Service
public class BaseClient extends BaseGenericService {

    private final WebClient webClient;

    protected BaseClient(WebClient.Builder builder) {
        this.webClient = builder.baseUrl("https://www.rippling.com/")
                .defaultHeader("Accept", "application/json")
                .build();
    }

    public Flux<JsonNode> getFlux(String path, MultiValueMap<String, String> queryParams) {
        return this.getFlux(path, queryParams, JsonNode.class);
    }

    public <T> Flux<T> getFlux(String path, MultiValueMap<String, String> queryParams, Class<T> responseType) {
        return this.webClient.get().uri(uriBuilder -> uriBuilder.path(path).queryParams(queryParams).build())
                .retrieve()
                .bodyToFlux(responseType);

    }

    public Mono<JsonNode> get(String path, MultiValueMap<String, String> queryParams) {
        return this.get(path, queryParams, JsonNode.class);
    }

    public <T> Mono<T> get(String path, MultiValueMap<String, String> queryParams, Class<T> responseType) {
        return this.webClient.get().uri(uriBuilder -> uriBuilder.path(path).queryParams(queryParams).build())
                .retrieve()
                .bodyToMono(responseType);
    }

    public Mono<JsonNode> put(String path, Object body) {
        return this.webClient.put().uri(uriBuilder -> uriBuilder.path(path).build())
                .bodyValue(body)
                .retrieve()
                .bodyToMono(JsonNode.class);
    }

    public Mono<JsonNode> delete(String path, String id) {
        return this.webClient.delete().uri(uriBuilder -> uriBuilder.path(path).build(id))
                .retrieve()
                .bodyToMono(JsonNode.class);
    }

    public Mono<JsonNode> post(String path, Object body) {
        return this.webClient.post().uri(uriBuilder -> uriBuilder.path(path).build())
                .bodyValue(body)
                .retrieve()
                .bodyToMono(JsonNode.class);
    }

    public WebClient getWebClient() {
        return webClient;
    }
}
